Skip to content

Commit 0b1547d

Browse files
committed
Tests for new API Temporal.TimeZone.p.equals
1 parent 85e2b49 commit 0b1547d

20 files changed

+1297
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: Tests that objects can be compared for equality
7+
features: [Temporal]
8+
---*/
9+
10+
class CustomTimeZone extends Temporal.TimeZone {
11+
constructor(id) {
12+
super("UTC");
13+
this._id = id;
14+
}
15+
get id() {
16+
return this._id;
17+
}
18+
}
19+
20+
const objectsEqualUTC = [
21+
new Temporal.TimeZone("UTC"),
22+
new CustomTimeZone("UTC"),
23+
{ id: "UTC", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
24+
new Temporal.ZonedDateTime(0n, "UTC")
25+
];
26+
27+
const tzUTC = new Temporal.TimeZone("UTC");
28+
29+
for (const object of objectsEqualUTC) {
30+
const result = tzUTC.equals(object);
31+
assert.sameValue(result, true, `Receiver ${tzUTC.id} should equal argument ${object.id}`);
32+
}
33+
34+
const objectsEqual0000 = [
35+
new Temporal.TimeZone("+00:00"),
36+
new Temporal.TimeZone("+0000"),
37+
new Temporal.TimeZone("+00"),
38+
new CustomTimeZone("+00:00"),
39+
new CustomTimeZone("+0000"),
40+
new CustomTimeZone("+00"),
41+
{ id: "+00:00", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
42+
{ id: "+0000", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
43+
{ id: "+00", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
44+
new Temporal.ZonedDateTime(0n, "+00:00"),
45+
new Temporal.ZonedDateTime(0n, "+0000"),
46+
new Temporal.ZonedDateTime(0n, "+00"),
47+
"+00:00",
48+
"+0000",
49+
"+00"
50+
];
51+
52+
const tz0000ToTest = [
53+
new Temporal.TimeZone("+00:00"),
54+
new Temporal.TimeZone("+0000"),
55+
new Temporal.TimeZone("+00"),
56+
new CustomTimeZone("+00:00"),
57+
new CustomTimeZone("+0000"),
58+
new CustomTimeZone("+00")
59+
];
60+
61+
for (const arg of objectsEqual0000) {
62+
for (const receiver of tz0000ToTest) {
63+
const result = receiver.equals(arg);
64+
assert.sameValue(result, true, `Receiver ${receiver.id} should equal argument ${arg.id ?? arg}`);
65+
}
66+
}
67+
68+
const objectsNotEqual = [
69+
new Temporal.TimeZone("+00:00"),
70+
new CustomTimeZone("+00:00"),
71+
new CustomTimeZone("Etc/Custom"),
72+
{ id: "+00:00", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
73+
{ id: "Etc/Custom", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
74+
new Temporal.ZonedDateTime(0n, "+00:00"),
75+
"UTC"
76+
];
77+
78+
const customObjectsToTest = [tzUTC, new CustomTimeZone("YouTeeSee"), new CustomTimeZone("+01:00")];
79+
80+
for (const arg of objectsNotEqual) {
81+
for (const receiver of customObjectsToTest) {
82+
if (arg === "UTC" && receiver === tzUTC) continue;
83+
const result = receiver.equals(arg);
84+
assert.sameValue(result, false, `Receiver ${receiver.id} should not equal argument ${arg.id ?? arg}`);
85+
}
86+
}
87+
88+
// Custom object IDs are compared case-sensitively
89+
const classInstanceCustomId = new CustomTimeZone("Moon/Cheese");
90+
const classInstanceSameCaseCustomId = new CustomTimeZone("Moon/Cheese");
91+
const classInstanceDifferentCaseCustomId = new CustomTimeZone("MoOn/CHEESe");
92+
93+
const plainObjectSameCaseCustomId = { id: "Moon/Cheese", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null };
94+
const plainObjectDifferentCaseCustomId = {
95+
id: "MoOn/CHEESe",
96+
getPossibleInstantsFor: null,
97+
getOffsetNanosecondsFor: null
98+
};
99+
100+
assert.sameValue(classInstanceCustomId.equals(classInstanceSameCaseCustomId), true);
101+
assert.sameValue(classInstanceCustomId.equals(classInstanceDifferentCaseCustomId), false);
102+
assert.sameValue(classInstanceCustomId.equals(plainObjectSameCaseCustomId), true);
103+
assert.sameValue(classInstanceCustomId.equals(plainObjectDifferentCaseCustomId), false);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.from
6+
description: Exceptions thrown if a value is passed that converts to an invalid string
7+
features: [Temporal]
8+
---*/
9+
10+
const primitives = [
11+
undefined,
12+
null,
13+
true,
14+
"string",
15+
"local",
16+
"Z",
17+
"-00:00[UTC]",
18+
"+00:01.1",
19+
"-01.1",
20+
"1994-11-05T08:15:30+25:00",
21+
"1994-11-05T13:15:30-25:00",
22+
7,
23+
4.2,
24+
12n
25+
];
26+
27+
const tzUTC = new Temporal.TimeZone("UTC");
28+
for (const primitive of primitives) {
29+
assert.throws(typeof primitive === "string" ? RangeError : TypeError, () => tzUTC.equals(primitive));
30+
}
31+
32+
const symbol = Symbol();
33+
assert.throws(TypeError, () => tzUTC.equals(symbol));
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.from
6+
description: Built-in time zones are compared correctly out of valid strings
7+
features: [Temporal]
8+
---*/
9+
10+
const validsEqual = [
11+
["+0330", "+03:30"],
12+
["-0650", "-06:50"],
13+
["-08", "-08:00"],
14+
["\u221201:00", "-01:00"],
15+
["\u22120650", "-06:50"],
16+
["\u221208", "-08:00"],
17+
["1994-11-05T08:15:30-05:00", "-05:00"],
18+
["1994-11-05T08:15:30\u221205:00", "-05:00"],
19+
["1994-11-05T13:15:30Z", "UTC"]
20+
];
21+
22+
for (const [valid, canonical] of validsEqual) {
23+
const tzValid = Temporal.TimeZone.from(valid);
24+
const tzCanonical = Temporal.TimeZone.from(canonical);
25+
assert.sameValue(tzValid.equals(canonical), true);
26+
assert.sameValue(tzCanonical.equals(valid), true);
27+
}
28+
29+
const validsNotEqual = [
30+
["+0330", "+03:31"],
31+
["-0650", "-06:51"],
32+
["-08", "-08:01"],
33+
["\u221201:00", "-01:01"],
34+
["\u22120650", "-06:51"],
35+
["\u221208", "-08:01"],
36+
["1994-11-05T08:15:30-05:00", "-05:01"],
37+
["1994-11-05T08:15:30\u221205:00", "-05:01"]
38+
];
39+
40+
for (const [valid, canonical] of validsNotEqual) {
41+
const tzValid = Temporal.TimeZone.from(valid);
42+
const tzCanonical = Temporal.TimeZone.from(canonical);
43+
assert.sameValue(tzValid.equals(canonical), false);
44+
assert.sameValue(tzCanonical.equals(valid), false);
45+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: Throw a TypeError if the receiver is invalid
7+
features: [Symbol, Temporal]
8+
---*/
9+
10+
const equals = Temporal.TimeZone.prototype.equals;
11+
12+
assert.sameValue(typeof equals, "function");
13+
14+
const args = ["UTC"];
15+
16+
assert.throws(TypeError, () => equals.apply(undefined, args), "undefined");
17+
assert.throws(TypeError, () => equals.apply(null, args), "null");
18+
assert.throws(TypeError, () => equals.apply(true, args), "true");
19+
assert.throws(TypeError, () => equals.apply("", args), "empty string");
20+
assert.throws(TypeError, () => equals.apply(Symbol(), args), "symbol");
21+
assert.throws(TypeError, () => equals.apply(1, args), "1");
22+
assert.throws(TypeError, () => equals.apply({}, args), "plain object");
23+
assert.throws(TypeError, () => equals.apply(Temporal.TimeZone, args), "Temporal.TimeZone");
24+
assert.throws(TypeError, () => equals.apply(Temporal.TimeZone.prototype, args), "Temporal.TimeZone.prototype");
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: >
7+
Tests that Temporal.TimeZone.prototype.equals
8+
meets the requirements for built-in objects defined by the
9+
introduction of chapter 17 of the ECMAScript Language Specification.
10+
info: |
11+
Built-in functions that are not constructors do not have a "prototype" property unless
12+
otherwise specified in the description of a particular function.
13+
14+
Unless specified otherwise, a built-in object that is callable as a function is a built-in
15+
function object with the characteristics described in 10.3. Unless specified otherwise, the
16+
[[Extensible]] internal slot of a built-in object initially has the value true.
17+
18+
Unless otherwise specified every built-in function and every built-in constructor has the
19+
Function prototype object [...] as the value of its [[Prototype]] internal slot.
20+
features: [Temporal]
21+
---*/
22+
23+
assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.equals),
24+
true, "Built-in objects must be extensible.");
25+
26+
assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.equals),
27+
"[object Function]", "Object.prototype.toString");
28+
29+
assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.equals),
30+
Function.prototype, "prototype");
31+
32+
assert.sameValue(Temporal.TimeZone.prototype.equals.hasOwnProperty("prototype"),
33+
false, "prototype property");
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (C) 2023 Justin Grant All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: TypeError thrown if time zone reports an id that is not a String
7+
features: [Temporal]
8+
---*/
9+
10+
class CustomTimeZone extends Temporal.TimeZone {
11+
constructor(id) {
12+
super("UTC");
13+
this._id = id;
14+
}
15+
get id() {
16+
return this._id;
17+
}
18+
}
19+
20+
[
21+
undefined,
22+
null,
23+
true,
24+
-1000,
25+
Symbol(),
26+
3600_000_000_000n,
27+
{},
28+
{
29+
valueOf() {
30+
return 3600_000_000_000;
31+
}
32+
}
33+
].forEach((wrongId) => {
34+
const timeZoneWrong = new CustomTimeZone(wrongId);
35+
const timeZoneOK = new Temporal.TimeZone('UTC');
36+
assert.throws(TypeError, () => timeZoneWrong.equals(timeZoneOK));
37+
assert.throws(TypeError, () => timeZoneOK.equals(timeZoneWrong));
38+
});
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: Temporal.TimeZone.prototype.equals.length is 1
7+
info: |
8+
Every built-in function object, including constructors, has a "length" property whose value is
9+
an integer. Unless otherwise specified, this value is equal to the largest number of named
10+
arguments shown in the subclause headings for the function description. Optional parameters
11+
(which are indicated with brackets: [ ]) or rest parameters (which are shown using the form
12+
«...name») are not included in the default argument count.
13+
14+
Unless otherwise specified, the "length" property of a built-in function object has the
15+
attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
16+
includes: [propertyHelper.js]
17+
features: [Temporal]
18+
---*/
19+
20+
verifyProperty(Temporal.TimeZone.prototype.equals, "length", {
21+
value: 1,
22+
writable: false,
23+
enumerable: false,
24+
configurable: true,
25+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: Temporal.TimeZone.prototype.equals.name is "equals".
7+
info: |
8+
Every built-in function object, including constructors, that is not identified as an anonymous
9+
function has a "name" property whose value is a String. Unless otherwise specified, this value
10+
is the name that is given to the function in this specification.
11+
12+
Unless otherwise specified, the "name" property of a built-in function object, if it exists,
13+
has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
14+
includes: [propertyHelper.js]
15+
features: [Temporal]
16+
---*/
17+
18+
verifyProperty(Temporal.TimeZone.prototype.equals, "name", {
19+
value: "equals",
20+
writable: false,
21+
enumerable: false,
22+
configurable: true,
23+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: >
7+
Temporal.TimeZone.prototype.equals does not implement [[Construct]], is not new-able
8+
info: |
9+
Built-in function objects that are not identified as constructors do not implement the
10+
[[Construct]] internal method unless otherwise specified in the description of a particular
11+
function.
12+
includes: [isConstructor.js]
13+
features: [Reflect.construct, Temporal]
14+
---*/
15+
16+
assert.throws(TypeError, () => {
17+
new Temporal.TimeZone.prototype.equals();
18+
}, "Calling as constructor");
19+
20+
assert.sameValue(isConstructor(Temporal.TimeZone.prototype.equals), false,
21+
"isConstructor(Temporal.TimeZone.prototype.equals)");
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: The "equals" property of Temporal.TimeZone.prototype
7+
includes: [propertyHelper.js]
8+
features: [Temporal]
9+
---*/
10+
11+
assert.sameValue(
12+
typeof Temporal.TimeZone.prototype.equals,
13+
"function",
14+
"`typeof TimeZone.prototype.equals` is `function`"
15+
);
16+
17+
verifyProperty(Temporal.TimeZone.prototype, "equals", {
18+
writable: true,
19+
enumerable: false,
20+
configurable: true,
21+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.equals
6+
description: Time zone names are case insensitive
7+
features: [Temporal]
8+
---*/
9+
10+
const timeZone = 'UtC';
11+
const result = Temporal.TimeZone.from(timeZone);
12+
assert.sameValue(result.equals(timeZone), true);
13+
assert.sameValue(result.equals("+00:00"), false);

0 commit comments

Comments
 (0)